package bw.gui;

import bw.owl.Ontology;
import bw.owl.Pracownik;
import bw.owl.Umiejetnosc;
import bw.owl.Zadanie;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.swing.BoxLayout;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLAxiom;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLEquivalentClassesAxiom;
import org.semanticweb.owlapi.model.OWLIndividual;
import org.semanticweb.owlapi.model.OWLNamedIndividual;
import org.semanticweb.owlapi.model.OWLNegativeObjectPropertyAssertionAxiom;
import org.semanticweb.owlapi.model.OWLObjectOneOf;
import org.semanticweb.owlapi.model.OWLObjectProperty;
import org.semanticweb.owlapi.model.OWLObjectPropertyAssertionAxiom;
import org.semanticweb.owlapi.model.OWLOntologyChange;

public class PracownicyPanel extends JPanel implements ActionListener {

    private InstanceViewer parent;
    private GroupLayout layout;
    private JButton dodaj;
//    private JButton usun;
//    private JButton zmienNazwe;
    private JButton edytujUmiejetnosci;
    private JButton edytujZadania;
    private JList listaPracownikow;
    private JCheckBox czyWszyscy;

    public PracownicyPanel(InstanceViewer viewer) {
	parent = viewer;
        layout = new GroupLayout(this);
        setLayout(layout);

        layout.setAutoCreateGaps(true);
        layout.setAutoCreateContainerGaps(true);

        listaPracownikow = new JList();
        JScrollPane scrollPane = new JScrollPane(listaPracownikow);
        scrollPane.setMinimumSize(new Dimension(600, 100));

        dodaj = new JButton("Dodaj");
//        usun = new JButton("Usuń");
//        zmienNazwe = new JButton("Zmień nazwę");
        edytujUmiejetnosci = new JButton("Edytuj znane umiejętności");
        edytujZadania = new JButton("Edytuj wykonywane zadania");

        JLabel wszyscy = new JLabel("Czy wszyscy pracownicy firmy są znani?");
        czyWszyscy = new JCheckBox();

        layout.setHorizontalGroup(
                layout.createParallelGroup()
                .addComponent(scrollPane)
                .addGroup(layout.createSequentialGroup()
                    .addComponent(dodaj)
//                    .addComponent(usun)
//                    .addComponent(zmienNazwe)
                    )
                .addGroup(layout.createSequentialGroup()
                    .addComponent(edytujUmiejetnosci)
                    .addComponent(edytujZadania))
                .addGroup(layout.createSequentialGroup()
                    .addComponent(wszyscy)
                    .addComponent(czyWszyscy)));

        layout.setVerticalGroup(
                layout.createSequentialGroup()
                .addComponent(scrollPane)
                .addGroup(layout.createParallelGroup()
                    .addComponent(dodaj)
//                    .addComponent(usun)
//                    .addComponent(zmienNazwe)
                    )
                .addGroup(layout.createParallelGroup()
                    .addComponent(edytujUmiejetnosci)
                    .addComponent(edytujZadania))
                .addGroup(layout.createParallelGroup()
                    .addComponent(wszyscy)
                    .addComponent(czyWszyscy)));

        dodaj.addActionListener(this);
//        usun.addActionListener(this);
//        zmienNazwe.addActionListener(this);
        edytujUmiejetnosci.addActionListener(this);
        edytujZadania.addActionListener(this);
        czyWszyscy.addActionListener(this);
    }

    void setPracownicy(ArrayList<Pracownik> pracownicy2) {
        listaPracownikow.setListData(pracownicy2.toArray());
    }

    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == dodaj){
            dodaj();
	}
//        else if(e.getSource() == usun){
//            usun();
//        }
        else if(e.getSource() == edytujUmiejetnosci) {
            if(listaPracownikow.isSelectionEmpty()) {
        	komunikujBlad();
            }
            else {
        	edytujUmiejetnosci();
            }
        }
        else if(e.getSource() == edytujZadania) {

            if(listaPracownikow.isSelectionEmpty()) {
        	komunikujBlad();
            }
            else {
        	edytujZadania();
            }
        }
        else if(e.getSource() == czyWszyscy) {
            czyWszyscyChanged();
        }
    }

    private void komunikujBlad() {
	JOptionPane.showMessageDialog(this,
		    "Musisz zaznaczyć jednego pracownika!",
		    "Zaznacz pracownika",
		    JOptionPane.WARNING_MESSAGE);
    }
    
    private void dodaj() {
        final JFrame frame = new JFrame("Imię i Nazwisko:");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setLayout(new FlowLayout());
        final JTextField field = new JTextField(20);
        frame.add(field);
        JButton akceptuj = new JButton("OK");
        frame.add(akceptuj);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

	    akceptuj.addActionListener(new ActionListener() {

		public void actionPerformed(ActionEvent e) {
		    OWLNamedIndividual ind = Ontology.getFactory()
			    .getOWLNamedIndividual(
				    IRI.create(Ontology.getOwlString() + "#" +
					    field.getText()));

		    List<OWLOntologyChange> oc = new ArrayList<OWLOntologyChange>();

		    OWLClass klasaPracujaca = Ontology.getFactory()
			    .getOWLClass(
				    IRI.create(Ontology.getOwlString()
					    + "#Pracownik"));
		    OWLAxiom axiom = Ontology.getFactory()
			    .getOWLClassAssertionAxiom(klasaPracujaca, ind);
		    oc.addAll(Ontology.getManager().addAxiom(
			    Ontology.getOntology(), axiom));

		    Ontology.getManager().applyChanges(oc);
		    Ontology.reload();
		    parent.update();

		    frame.dispose();
		}
	    });
    }
    
    private void edytujZadania() {
	final Pracownik pracownik = (Pracownik) listaPracownikow.getSelectedValue();
	final OWLObjectProperty byloWykonywane = Ontology.getFactory().getOWLObjectProperty(
		IRI.create(Ontology.getOwlString() + "#byloWykonywane"));
	    
        final JFrame frame = new JFrame("Które zadania wykonywał?:");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.PAGE_AXIS));
        
        ArrayList<Zadanie> zadania = Ontology.getZadania();
        final ArrayList<PanelWyboruRol> panele = new ArrayList<PanelWyboruRol>();
        
        for(Zadanie z : zadania) {
            PanelWyboruRol panelWyboru = new PanelWyboruRol(z); 
            panele.add(panelWyboru);
            frame.add(panelWyboru);
            panelWyboru.setAlignmentX(LEFT_ALIGNMENT);
            
            try {
        	Set<OWLObjectPropertyAssertionAxiom> pozytywy = Ontology.getOntology()
        		.getObjectPropertyAssertionAxioms(z.getIndywidulum());
                OWLObjectPropertyAssertionAxiom tenKonkretnyPozytyw = Ontology.getFactory()
        		.getOWLObjectPropertyAssertionAxiom(
        			byloWykonywane, z.getIndywidulum(), pracownik.getIndywidulum());
                if(pozytywy.contains(tenKonkretnyPozytyw)) {
                    panelWyboru.setState(1);
                }
                Set<OWLNegativeObjectPropertyAssertionAxiom> negatywy = Ontology.getOntology()
                	.getNegativeObjectPropertyAssertionAxioms(z.getIndywidulum());
                OWLNegativeObjectPropertyAssertionAxiom tenKonkretnyNegatyw = Ontology.getFactory()
                	.getOWLNegativeObjectPropertyAssertionAxiom(
                		byloWykonywane, z.getIndywidulum(), pracownik.getIndywidulum());
                    
                if(negatywy.contains(tenKonkretnyNegatyw))
                    panelWyboru.setState(-1);
            }
            catch(Exception ex) {
        	ex.printStackTrace();
            }
            
        }
        
        JButton akceptuj = new JButton("OK");
        frame.add(akceptuj);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

	    akceptuj.addActionListener(new ActionListener() {

		public void actionPerformed(ActionEvent e) {

	            List<OWLOntologyChange> oc = new ArrayList<OWLOntologyChange>();
		    
		    for(int i = 0 ; i < panele.size() ; i++) {
			PanelWyboruRol panel = panele.get(i);
			Zadanie zadanie = (Zadanie) panele.get(i).getKoncept();
			if(panel.getState() == 1) {
			    // Wiemy, że wykonywał
			    OWLAxiom negaxiom = Ontology.getFactory().getOWLNegativeObjectPropertyAssertionAxiom(
				    byloWykonywane, zadanie.getIndywidulum(), pracownik.getIndywidulum());

			    oc.addAll(Ontology.getManager().removeAxiom(Ontology.getOntology(), negaxiom));

			    OWLAxiom axiom = Ontology.getFactory().getOWLObjectPropertyAssertionAxiom(
				    byloWykonywane, zadanie.getIndywidulum(), pracownik.getIndywidulum());

			    oc.addAll(Ontology.getManager().addAxiom(Ontology.getOntology(), axiom));
			}
			else if(panel.getState() == 0) {
			    // nie wiemy, czy wykonywal
			    OWLAxiom negaxiom = Ontology.getFactory().getOWLNegativeObjectPropertyAssertionAxiom(
				    byloWykonywane, zadanie.getIndywidulum(), pracownik.getIndywidulum());

			    oc.addAll(Ontology.getManager().removeAxiom(Ontology.getOntology(), negaxiom));
			    
			    OWLAxiom axiom = Ontology.getFactory().getOWLObjectPropertyAssertionAxiom(
				    byloWykonywane, zadanie.getIndywidulum(), pracownik.getIndywidulum());

			    oc.addAll(Ontology.getManager().removeAxiom(Ontology.getOntology(), axiom));
			}
			else if(panel.getState() == -1) {
			    // Wiemy, że nie wykonywał
			    OWLAxiom axiom = Ontology.getFactory().getOWLObjectPropertyAssertionAxiom(
				    byloWykonywane, zadanie.getIndywidulum(), pracownik.getIndywidulum());

			    oc.addAll(Ontology.getManager().removeAxiom(Ontology.getOntology(), axiom));

			    OWLAxiom negaxiom = Ontology.getFactory().getOWLNegativeObjectPropertyAssertionAxiom(
				    byloWykonywane, zadanie.getIndywidulum(), pracownik.getIndywidulum());

			    oc.addAll(Ontology.getManager().addAxiom(Ontology.getOntology(), negaxiom));
			}
			
		    }
		    
		    try {
			Ontology.getManager().applyChanges(oc);
			Ontology.reload();
			parent.update();
		    } catch (Exception ex) {
			ex.printStackTrace();
		    }

		    frame.dispose();
		}
	    });
    }
    
    private void edytujUmiejetnosci() {
	final Pracownik pracownik = (Pracownik) listaPracownikow.getSelectedValue();
	final OWLObjectProperty jestZnana = Ontology.getFactory().getOWLObjectProperty(
		IRI.create(Ontology.getOwlString() + "#jestZnana"));
	    
        final JFrame frame = new JFrame("Jakie umiejętności posiada?:");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.PAGE_AXIS));
        
        ArrayList<Umiejetnosc> umiejetnosci = Ontology.getUmiejetnosci();
        final ArrayList<PanelWyboruRol> panele = new ArrayList<PanelWyboruRol>();
        
        for(Umiejetnosc u : umiejetnosci) {
            PanelWyboruRol panelWyboru = new PanelWyboruRol(u); 
            panele.add(panelWyboru);
            frame.add(panelWyboru);
            panelWyboru.setAlignmentX(LEFT_ALIGNMENT);
            
            try {
        	Set<OWLObjectPropertyAssertionAxiom> pozytywy = Ontology.getOntology()
        		.getObjectPropertyAssertionAxioms(u.getIndywidulum());
                OWLObjectPropertyAssertionAxiom tenKonkretnyPozytyw = Ontology.getFactory()
        		.getOWLObjectPropertyAssertionAxiom(
        			jestZnana, u.getIndywidulum(), pracownik.getIndywidulum());
                if(pozytywy.contains(tenKonkretnyPozytyw)) {
                    panelWyboru.setState(1);
                }
                Set<OWLNegativeObjectPropertyAssertionAxiom> negatywy = Ontology.getOntology()
                	.getNegativeObjectPropertyAssertionAxioms(u.getIndywidulum());
                OWLNegativeObjectPropertyAssertionAxiom tenKonkretnyNegatyw = Ontology.getFactory()
                	.getOWLNegativeObjectPropertyAssertionAxiom(
                		jestZnana, u.getIndywidulum(), pracownik.getIndywidulum());
                    
                if(negatywy.contains(tenKonkretnyNegatyw))
                    panelWyboru.setState(-1);
            }
            catch(Exception ex) {
        	ex.printStackTrace();
            }
            
        }
        
        JButton akceptuj = new JButton("OK");
        frame.add(akceptuj);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

	    akceptuj.addActionListener(new ActionListener() {

		public void actionPerformed(ActionEvent e) {

	            List<OWLOntologyChange> oc = new ArrayList<OWLOntologyChange>();
		    
		    for(int i = 0 ; i < panele.size() ; i++) {
			PanelWyboruRol panel = panele.get(i);
			Umiejetnosc umiejetnosc = (Umiejetnosc) panele.get(i).getKoncept();
			if(panel.getState() == 1) {
			    // Wiemy, że zna
			    OWLAxiom negaxiom = Ontology.getFactory().getOWLNegativeObjectPropertyAssertionAxiom(
				    jestZnana, umiejetnosc.getIndywidulum(), pracownik.getIndywidulum());

			    oc.addAll(Ontology.getManager().removeAxiom(Ontology.getOntology(), negaxiom));

			    OWLAxiom axiom = Ontology.getFactory().getOWLObjectPropertyAssertionAxiom(
				    jestZnana, umiejetnosc.getIndywidulum(), pracownik.getIndywidulum());

			    oc.addAll(Ontology.getManager().addAxiom(Ontology.getOntology(), axiom));
			}
			else if(panel.getState() == 0) {
			    // nie wiemy, czy zna
			    OWLAxiom negaxiom = Ontology.getFactory().getOWLNegativeObjectPropertyAssertionAxiom(
				    jestZnana, umiejetnosc.getIndywidulum(), pracownik.getIndywidulum());

			    oc.addAll(Ontology.getManager().removeAxiom(Ontology.getOntology(), negaxiom));
			    
			    OWLAxiom axiom = Ontology.getFactory().getOWLObjectPropertyAssertionAxiom(
				    jestZnana, umiejetnosc.getIndywidulum(), pracownik.getIndywidulum());

			    oc.addAll(Ontology.getManager().removeAxiom(Ontology.getOntology(), axiom));
			}
			else if(panel.getState() == -1) {
			    // Wiemy, że nie zna
			    OWLAxiom axiom = Ontology.getFactory().getOWLObjectPropertyAssertionAxiom(
				    jestZnana, umiejetnosc.getIndywidulum(), pracownik.getIndywidulum());

			    oc.addAll(Ontology.getManager().removeAxiom(Ontology.getOntology(), axiom));

			    OWLAxiom negaxiom = Ontology.getFactory().getOWLNegativeObjectPropertyAssertionAxiom(
				    jestZnana, umiejetnosc.getIndywidulum(), pracownik.getIndywidulum());

			    oc.addAll(Ontology.getManager().addAxiom(Ontology.getOntology(), negaxiom));
			}
			
		    }
		    
		    try {
			Ontology.getManager().applyChanges(oc);
			Ontology.reload();
			parent.update();
		    } catch (Exception ex) {
			ex.printStackTrace();
		    }

		    frame.dispose();
		}
	    });
    }

    public void czyWszyscyChanged() {

	List<OWLOntologyChange> oc = new ArrayList<OWLOntologyChange>();

	OWLClass klasaPracujaca = Ontology.getFactory()
	.getOWLClass(
		IRI.create(Ontology.getOwlString()
			+ "#Pracownik"));

	if(czyWszyscy.isSelected()) {
	    ArrayList<Pracownik> pracownicy = Ontology.getPracownicy();
	    Set<OWLIndividual> pracownicyOWL = new HashSet<OWLIndividual>();
	    for(Pracownik p : pracownicy)
		pracownicyOWL.add(p.getIndywidulum());

	    OWLObjectOneOf set = Ontology.getFactory().getOWLObjectOneOf(pracownicyOWL);

	    OWLAxiom eqaxiom = Ontology.getFactory().getOWLEquivalentClassesAxiom(
		    klasaPracujaca,	set);

	    oc.addAll(Ontology.getManager().addAxiom(Ontology.getOntology(), eqaxiom));
	}
	else {
	    Set<OWLEquivalentClassesAxiom> eqaxioms = Ontology.getOntology().getEquivalentClassesAxioms(klasaPracujaca);

	    oc.addAll(Ontology.getManager().removeAxioms(Ontology.getOntology(), eqaxioms));
	}

	try {
	    Ontology.getManager().applyChanges(oc);
	    Ontology.reload();
	    parent.update();
	} catch (Exception ex) {
	    ex.printStackTrace();
	}
    }
}
